Skip to content

diff_pair: fix gf180 LVS pin labels and dummy net - #103

Merged
msaligane merged 1 commit into
ReaLLMASIC:mainfrom
carloscl03:fix-gf180-lvs-labels
Aug 27, 2026
Merged

diff_pair: fix gf180 LVS pin labels and dummy net#103
msaligane merged 1 commit into
ReaLLMASIC:mainfrom
carloscl03:fix-gf180-lvs-labels

Conversation

@carloscl03

Copy link
Copy Markdown
Contributor

diff_pair and diff_pair_ibias fail LVS on gf180 in main. Three
separate causes, all in how the cell describes itself rather than in its
geometry — DRC is clean before and after.

Pin labels land off metal

gf180 maps met*_pin and met*_label to the same non-conducting label
layer, so a marker drawn only there has no conductor under it. The markers
were also aligned ('c','b'), which places them tangent to the port edge
instead of on it:

label     on real metal    extracted
VDD1/VDD2      yes            yes      <- happen to sit over drain metal
VTAIL/VN/VP/B  no             no
.SUBCKT diff_pair VDD1 VDD2                    <- before
.SUBCKT diff_pair VDD1 B VTAIL VDD2 VN VP      <- after

current_mirror already centres its bulk label for this reason; its
comment describes the same failure. Factored the six copy-pasted marker
blocks into one helper while there.

Dummy S/D net chosen by PDK name

dum_net = 'B' if pdk.name == 'sky130' else 'dum'   # before
dum_net = 'B' if substrate_tap else 'dum'          # after

The cell routes its dummies to the tap ring whenever substrate_tap is
on, so both extractors report them on bulk — that follows the layout, not
the process. diff_pair_cmirrorbias already had to override this back to
'B', with a comment noting the standalone convention was wrong there.
Same reasoning retires the ## HACK ... likely incorrect PDK check on the
cmirror dummies.

Sub-cell labels leak into the parent

VTAIL is a top-level pin of a standalone diff_pair but an internal net
inside diff_pair_ibias, so the inherited label extracted as an extra
top-level pin. low_voltage_cmirror solves this with a GLAYOUT_NO_PIN_LABELS
save/set/restore block; this adds that as a no_pin_labels() context
manager in port_utils and uses it, rather than copy-pasting the block.

Validation

Ran the repo's own runners on both PDKs:

gf180 before gf180 after sky130 before sky130 after
DRC 9/9 9/9 9/9 9/9
LVS 5/8 7/8 8/8 8/8

opamp still fails LVS on gf180 (unchanged by this PR). Its nwell tap
stack tops out one via below the vdd rail, so the nwell extracts as an
unnamed net and every PMOS bulk goes with it — happy to open that
separately with the measurements.

Pin markers were drawn on hardcoded sky130 layer numbers -- met1_pin
(67,16), met1_label (67,5), met2_pin (68,16), met2_label (68,5) -- which
mean nothing on gf180. They now come from the PDK.

They were also sized and placed so that the marker carried only the label
layer, tangent to the port's edge rather than centred on it. The extractor
then finds no conductor under the text, the net comes out unnamed, and LVS
reports the pin as missing from the layout. The marker is now sized to the
routable metal's minimum width and aligned centre-to-centre, so it lands
inside metal the router already placed.

Rebased onto current main. The `no_pin_labels()` context manager this branch
originally added is dropped: ReaLLMASIC#105 landed `with_pin_labels` on diff_pair, and
ReaLLMASIC#112 handles the general case in the LVS runner, where it needs no
cooperation from any cell and does not depend on ambient state that `@cell`
cannot see.
@carloscl03
carloscl03 force-pushed the fix-gf180-lvs-labels branch from bbd904c to e77c058 Compare August 22, 2026 11:59
@carloscl03

Copy link
Copy Markdown
Contributor Author

Rebased onto current main; mergeable again, and narrowed to what is still needed.

The no_pin_labels() context manager is dropped. #105 landed with_pin_labels on diff_pair, and #112 handles the general case in the LVS runner — the reference netlist decides which labels are pins, so no cell has to cooperate and there is no ambient state for @cell to cache around. port_utils.py is untouched now.

What remains is the part nothing else covers. The pin markers were drawn on hardcoded sky130 layer numbers:

met1_pin = (67,16)   met1_label = (67,5)
met2_pin = (68,16)   met2_label = (68,5)

Those mean nothing on gf180, and the marker was placed tangent to the port's edge carrying only the label layer. The extractor then finds no conductor under the text, the net comes out unnamed, and LVS reports the pin as missing from the layout — which is the shape of main's current diff_pair failure (extra top-level pin(s) in layout: SUB). The markers now come from the PDK, are sized to the routable metal's minimum width, and are aligned centre-to-centre so they land inside metal the router already placed.

Two files, one commit.

@msaligane
msaligane merged commit 26d895e into ReaLLMASIC:main Aug 27, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants